package org.apache.ibatis.demo.plugin;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Statement;
import java.util.Properties;

/**
 * 完成插件签名：
 *    告诉MyBatis当前插件用来拦截哪个对象的哪个方法
 */
@Intercepts({
  @Signature(type = StatementHandler.class, method = "parameterize", args = Statement.class)
})
public class MyFirstPlugin implements Interceptor {
  /**
   * 拦截目标对象的目标方法的执行
   * @param invocation
   * @return
   * @throws Throwable
   */
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("MyFirstPlugin...intercet:" + invocation.getMethod());
    Object target = invocation.getTarget();
    System.out.println("当前拦截到的对象：" + target);
    MetaObject metaObject = SystemMetaObject.forObject(target);
    Object value = metaObject.getValue("parameterHandler.parameterObject");
    System.out.println("sql语句用的参数是：" + value);
    //修改完sql语句要用到的参数
    metaObject.setValue("parameterHandler.parameterObject", 1);
    //执行目标方法
    Object proceed = invocation.proceed();
    //返回执行后的返回值
    return proceed;
  }

  /**
   * plugin：包装目标对象；为目标对象创建一个代理对象
   * @param target
   * @return
   */
  @Override
  public Object plugin(Object target) {
    System.out.println("MyFirstPlugin...plugin:" + target);
    Object wrap = Plugin.wrap(target, this);
    //返回当前target创建的动态代理对象
    return wrap;
  }

  /**
   * 将插件注册时的property属性设置进来
   * @param properties
   */
  @Override
  public void setProperties(Properties properties) {
    System.out.println("插件配置的信息" + properties);
  }
}
